import React, {Component, Fragment} from "react";
import TodoItem from './TodoItem'
import axios from "axios";
import './mock/list'
import './input.css'

class TodoList extends Component {
    constructor(props) {
        super(props);
        this.state = {
            inputValue: '',
            list: []
        }
        this.handleInputChange = this.handleInputChange.bind(this);
        this.handleBtnClick = this.handleBtnClick.bind(this);
        this.handleDeleteItem = this.handleDeleteItem.bind(this);
    }

    /**
     * 在父组件里面输入内容的时候，子组件都要被重新的渲染
     * 当在输入框里面输入内容的时候，TodoList这个父组件的state发生了变化，所以TodoList的render函数就会被执行
     * 当父组件的render函数被执行时，子组件的render函数也会被执行，这个逻辑是没有问题的，但是会带来性能损耗
     * 性能优化：
     *  这个时候就可以使用子组件的生命周期函数 shouldComponentUpdate 这个方法做性能优化了，当组件需要更新的时候，要先询问组件是否需要真正被更新
     *
     * @returns {JSX.Element}
     */
    render() {

        return (
            <Fragment>
                <label htmlFor="inputContent">输入内容</label>
                <input
                    type="text"
                    id='inputContent'
                    value={this.state.inputValue}
                    onChange={this.handleInputChange}
                    className='input'
                />
                <button onClick={this.handleBtnClick}>提交</button>
                <ul>
                    {
                        this.getTodoItem()
                    }
                </ul>
            </Fragment>
        );
    }

    /**
     * 一般把AJAX请求的发起写在这个函数里面
     * 放到render函数里面会造成死循环，因为render函数会重复的执行，只要数据改变，都要重新的发一次AJAX请求，
     * 那么这样显然是不合理的
     *
     * componentDidMount只会执行一次，即组件被挂载到页面上的时候会被执行一次，之后就不会被重新重复的执行了
     * 只有我们把AJAX 请求放到这里是比较合适的
     *
     * componentWillMount：可以，但会和以后更高端的技术产生冲突
     * constructor：里面也是可以，不建议放
     *
     *
     */
    componentDidMount() {
        axios.get('/api/todolist')
            .then((res) => {
                console.log(res.data.data)
                this.setState(() => ({
                    // list: res.data.data
                    list: [...res.data.data]//最好的写法
                }))
            })
            .catch(() => {
                alert('error')
            })
    }

    handleInputChange(e) {
        const value = e.target.value;
        this.setState(() => (
            {
                inputValue: value
            }
        ));
    }

    handleBtnClick() {
        this.setState((prevState) => ({
            list: [...prevState.list, prevState.inputValue],
            inputValue: ''
        }))
    }

    getTodoItem() {
        return this.state.list.map((item, index) => {
            return <TodoItem
                key={index}
                context={item}
                index={index}
                handleDeleteItem={this.handleDeleteItem}
            />;
        })
    }

    handleDeleteItem(index) {
        this.setState((prevState) => {
            let list = [...prevState.list];
            list.splice(index, 1);
            return {
                list
            }
        })

    }
}

export default TodoList;